package com.tianyadu.security.controller.async;

import com.tianyadu.security.utils.KeyUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.async.DeferredResult;

import java.util.concurrent.Callable;

/**
 * @FileName: AsyncController
 * @Description: 异步请求处理控制类
 * @author: xueyj
 * @create: 2018-12-05 15:00
 */
@RestController
@Slf4j
@RequestMapping("/order")
public class AsyncController {

    /**
      * @Description: 同步处理订单信息
      * @param:
      * @return:
      * @author:
      * @date:   2018/12/5 15:12
      */
    @RequestMapping("/synchroCreateOrder")
    public String synchroCreateOrder() throws Exception {
        log.info("主线程调用开始");
        Thread.sleep(1000);
        log.info("主线程调用结束");
        return "success";
    }

    /**
      * @Description: 使用Callable副线程处理订单信息（依赖于主线程）
      * @param:
      * @return:
      * @author:
      * @date:   2018/12/5 17:13
      */
    @RequestMapping("/createOrderByCallable")
    public Callable<String> createOrderByCallable() throws Exception {
        log.info("主线程调用开始");
        Callable<String> result = new Callable<String>() {
            @Override
            public String call() throws Exception {
                log.info("副线程调用开始");
                Thread.sleep(1000);
                log.info("副线程调用结束");
                return "success";
            }
        };
        log.info("主线程调用结束");
        return result;
    }


    @Autowired
    private MockQueue mockQueue;

    @Autowired
    private DeferredResultHolder deferredResultHolder;

    /**
      * @Description: 使用DeferredResult异步处理订单信息（脱离当前主线程）
      * @param:
      * @return:
      * @author:
      * @date:   2018/12/5 17:53
      */
    @RequestMapping("/createOrderByDeferredResult")
    public DeferredResult<String> createOrderByDeferredResult() throws Exception {
        log.info("主线程调用开始");

        // 生成订单号信息
        String orderNumber = KeyUtil.genUniqueKey();
        //  将订单信息存放至消息队列中
        mockQueue.setPlaceOrder(orderNumber);
        //  传递订单信息至DeferredResult
        DeferredResult<String> result = new DeferredResult<>();
        deferredResultHolder.getMap().put(orderNumber, result);
        return result;
    }
}